import { ISwaggerConfig, Operation, Schema } from './swagger2.0';

/**
 * yaml配置文件的类型
 */
export interface IYamlConfig {
  yamlMap: IYamlConfigItem[];
  customUtil?: boolean;
}

export interface IYamlConfigItem {
  path: string;
  name: string;
  typeOutputPath: string;
  serviceOutputPath?: string;
  generateWidgetEnum?: boolean;
  generateUtils?: boolean;
  language?: LanguageEnum;
  isOnline?: boolean;
}

export interface IMethodTransformParam {
  method: IMethodType,
  language: LanguageEnum,
  path: string,
  config: Operation,
  swagger: ISwaggerConfig,
}

export interface ISchemaTransformParam {
  schema: Schema,
  name: string,
  language: LanguageEnum,
  definitions: Record<string, Schema>,
  returnMapper?: { [key: string]: ISchemaReturn },
  isTopLevel?: boolean,
}

/**
 * 文件接口列表，定义为对象类型
 */
export interface IInterfacesMapper {
  [key: string]: IInterfaceConfig;
}

export type IInterfaceConfig =
  ISimpleInterfaceConfig | // 简单类型
  IRefInterfaceConfig | // 引用类型
  IEnumInterfaceConfig | // 枚举类型
  IComplexInterfaceConfig | // 复杂类型(对象类型)
  IIntersetionInterfaceConfig | // 交叉类型(多个简单类型的交叉: A & B)
  IArrayInterfaceConfig; // 数组类型

export interface ISimpleInterfaceConfig {
  interfaceType: 'SIMPLE',
  descriptions: string[];
  displayType: string;
  refs: RefItem[];
  required: boolean;
  apifoxRefs?: RefItem[];
  apifoxProps?: string[];
}

export interface IRefInterfaceConfig {
  interfaceType: 'REF';
  config: {
    refConfig: IInterfaceConfig;
  }
  descriptions: string[];
  displayType: string;
  refs: RefItem[];
  required: boolean;
  apifoxRefs?: RefItem[];
  apifoxProps?: string[];
}

export interface IEnumInterfaceConfig {
  interfaceType: 'ENUM';
  descriptions: string[];
  config: {
    type: 'string' | 'number';
    enums: Array<{ enumKey: string; enumValue: string | number }>;
  };
  displayType: string;
  refs: RefItem[];
  required: boolean;
  apifoxRefs?: RefItem[];
  apifoxProps?: string[];
}

export interface IComplexInterfaceConfig {
  interfaceType: 'OBJECT';
  descriptions: string[];
  required: boolean;
  displayType: string;
  apifoxRefs: RefItem[];
  apifoxProps?: string[];
  isEmpty?: boolean;
  config: Record<string, IInterfaceConfig>;
  refs: RefItem[];
}

export interface IIntersetionInterfaceConfig {
  interfaceType: 'INTERSECTION';
  descriptions: string[];
  config: Array<ISimpleInterfaceConfig | IRefInterfaceConfig | IComplexInterfaceConfig>;
  displayType: string;
  refs: RefItem[];
  required: boolean;
  apifoxRefs?: RefItem[];
  apifoxProps?: string[];
}

export interface IArrayInterfaceConfig {
  interfaceType: 'ARRAY';
  descriptions: string[];
  config: ISimpleInterfaceConfig
  | IIntersetionInterfaceConfig
  | IRefInterfaceConfig
  | IEnumInterfaceConfig
  | IComplexInterfaceConfig;
  displayType: string;
  refs: RefItem[];
  required: boolean;
  apifoxRefs?: RefItem[];
  apifoxProps?: string[];
}

export interface RefItem {
  ref: string;
  refFileBasename: string;
  refFileRelativeUrl: string;
}

export interface ISchemaReturn {
  interfaceConfig: IInterfaceConfig;
  extraInterfaces?: IInterfacesMapper;
}

export interface IGenerateFormatConfig {
  serviceConfig: IServiceConfig;
  interfaceConfig: ITypeConfig;
}

export interface IServiceConfig {
  services: IServiceItemConfig[];
  info: {
    title: string;
    version: string;
    descriptions: string[];
  };
}

export interface IServiceItemConfig {
  serviceName: string;
  baseUrl: string;
  description: string;
  methods: IMethodConfig[];
  types: IInterfaceConfig[];
}

export type IMethodType = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch';

export interface IMethodConfig {
  methodName: string;
  summarys: string[];
  descriptions: string[];
  path: string;
  method: IMethodType;
  parameters: {
    path?: ISchemaReturn | null;
    query?: ISchemaReturn | null;
    body?: ISchemaReturn | null;
    header?: ISchemaReturn | null;
    formData?: ISchemaReturn | null;
  };
  response: ISchemaReturn | null;
  extraInterface: IInterfacesMapper;
}

export interface ITypeConfig {
  interfaceConfig: IInterfacesMapper;
}

export enum LanguageEnum {
  TYPESCRIPT = 'typescript',
  DART = 'dart',
}
